<template>
  <div ref="container" class="scene-container"></div>
</template>

<script setup>
import { onMounted, ref, nextTick } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js'

const container = ref()
let popupObject = null // 当前弹窗
let cube = null        // 全局 cube

onMounted(() => {
  const scene = new THREE.Scene()
  const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000)
  camera.position.set(0, 0, 10)

  const renderer = new THREE.WebGLRenderer({ antialias: true })
  renderer.setSize(window.innerWidth, window.innerHeight)
  container.value.appendChild(renderer.domElement)

  const labelRenderer = new CSS3DRenderer()
  labelRenderer.setSize(window.innerWidth, window.innerHeight)
  labelRenderer.domElement.style.position = 'absolute'
  labelRenderer.domElement.style.top = '0'
  labelRenderer.domElement.style.left = '0'
  labelRenderer.domElement.style.pointerEvents = 'none' // 防止拦截鼠标
  container.value.appendChild(labelRenderer.domElement)

  const controls = new OrbitControls(camera, renderer.domElement)

  // 创建正方体
  cube = new THREE.Mesh(
    new THREE.BoxGeometry(),
    new THREE.MeshNormalMaterial()
  )
  scene.add(cube)

  // 点击检测
  const raycaster = new THREE.Raycaster()
  const mouse = new THREE.Vector2()

  container.value.addEventListener('click', (event) => {
    const rect = container.value.getBoundingClientRect()
    mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1
    mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1

    raycaster.setFromCamera(mouse, camera)
    const intersects = raycaster.intersectObject(cube)

    if (intersects.length > 0) {
      // 打开弹窗
      openPopup()
    }
  })

  function openPopup() {
    // 若已存在弹窗则移除
    if (popupObject) {
      cube.remove(popupObject)
      popupObject = null
    }

    // 创建 HTML 弹窗
    const div = document.createElement('div')
    div.className = 'popup'
    div.innerHTML = `
      <div class="popup-header">
        属性弹窗
        <span class="popup-close">✖</span>
      </div>
      <div>大小: 1<br>颜色: 默认</div>
    `

    div.style.pointerEvents = 'auto' // 让其能响应事件

    popupObject = new CSS3DObject(div)
    popupObject.position.set(1.2, 1.2, 0)
    cube.add(popupObject)

    // 等下一个 tick 绑定事件（确保元素挂载完成）
    nextTick(() => {
      const closeBtn = div.querySelector('.popup-close')
      if (closeBtn) {
        closeBtn.addEventListener('click', (e) => {
          e.stopPropagation() // 阻止事件向上冒泡
          cube.remove(popupObject)
          popupObject = null
        })
      }
    })
  }

  // 动画循环
  const animate = () => {
    requestAnimationFrame(animate)
    renderer.render(scene, camera)
    labelRenderer.render(scene, camera)
  }
  animate()

  window.addEventListener('resize', () => {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
    labelRenderer.setSize(window.innerWidth, window.innerHeight)
  })
})
</script>

<style scoped>
.scene-container {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  position: relative;
}

.popup {
  background: rgba(255, 255, 255, 0.95);
  border: 1px solid #ccc;
  border-radius: 8px;
  padding: 10px;
  font-size: 14px;
  width: 150px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
  pointer-events: auto; /* 重要：否则事件无效 */
}

.popup-header {
  font-weight: bold;
  display: flex;
  justify-content: space-between;
  margin-bottom: 5px;
}

.popup-close {
  cursor: pointer;
  color: #888;
  user-select: none;
}
.popup-close:hover {
  color: red;
}
</style>
